<template>
  <div class="page">
    <div class="bg-text">
      <div class="bg-text-l">
        <img src="./assets/images/icon-bg.png" alt="">
        <div class="bg-texts">可交互动画</div>
      </div>
      <div class="bg-text-r">ROS消息动画</div>
    </div>
    <canvas id="canvas" ref="canvas"></canvas>
    <div class="title">ROS Topic</div>
    <div class="content">
      <div class="content-l">
        <div class="header">
          <!-- 新增节点 -->
          <div class="addNode" @click="addNode">
            <div class="header-text">新增节点</div>
            <img class="header-ioc" src="./assets/images/add.png" alt="">
          </div>
          <!-- 删除节点 -->
          <div class="deleteNode" @click="deleteNode">
            <div class="header-text">删除节点</div>
            <img class="header-ioc" src="./assets/images/delete.png" alt="">
          </div>
          <!-- 编辑节点 -->
          <div class="editNode" @click="editNode">
            <div class="header-text">编辑修改</div>
            <img class="header-ioc" src="./assets/images/edit.png" alt="">
          </div>
          <!-- 复位节点 -->
          <div class="resetNode" @click="resetNode">
            <div class="header-text">清除</div>
            <img class="header-ioc" src="./assets/images/reset.png" alt="">
          </div>
        </div>
        <div class="body">
          <!-- 上部分 订阅发布 -->
          <div class="publish-subscribe-top">
            <template v-for="(item, index) in dataList.clientOne" :key="index">
              <div v-if="item.isEmpyt" class="pubSub-none"></div>
              <div v-else class="pubSub-item" @click.self="getDomNode($event)">
                <div class="mask" v-show="maskDelet || maskEdit"></div>
                <div class="publish-title">
                  <text class="text">{{ item.title }}</text>
                  <img class="pubSub-img" src="./assets/images/right_arrow.png" alt=""
                    @click="handlePublish($event, index, 'clientOne', item)">
                </div>
                <input class="node" :class="{ 'node-focused': item.focus }" type="text" placeholder="Node"
                  v-model="item.node" @dblclick="handleDataEdit(item, index, 'clientOne')"
                  @focus="handleFocus('publish', index)" @blur="handleBlur('publish', index)">
                <div class="publish-bottom">
                  <text class="text">{{ item.subscribe }}</text>
                  <img class="pubSub-img" src="./assets/images/letf_arrow.png" alt=""
                    @click="handleSubscribe($event, index, 'clientOne', item.unique)">
                </div>
                <div class="delete_btn" v-show="maskDelet">
                  <img src="./assets/images/delete_ioc.png" alt="" @click="dataDelete(index, 'clientOne')">
                </div>
                <div class="edit_btn" v-show="maskEdit">
                  <img src="./assets/images/edit_ioc.png" alt="" @click="handleDataEdit(item, index, 'clientOne')">
                </div>
                <!-- 弹出框 -->
                <!-- <div class="popup" v-if="item.isPopup">
                  <div class="popup-top">
                    <div class="popup-title">{{item.topic}}</div>
                    <img src="./assets/images/fork.png" alt="">
                  </div>
                  <div class="popup-context">
                    <input v-model="item.value" class="input-text" type="text" >
                    <img src="./assets/images/sure.png" alt="">
                  </div>
                </div> -->
              </div>
            </template>
          </div>
          <!-- 话题 -->
          <div class="topic">
            <template class="topic-box" v-for="(el, index) in dataList.topic" :key="index">
              <div v-if="el.isEmpyt" class="topic-item-none"></div>
              <div v-else class="topic-items" @click="getDomNode($event)">
                <div class="topic-tip">
                  <!-- <input class="tip-text" type="text" v-model="el.title" /> -->
                  <div class="tip-text" type="text" @dblclick="handlePopup(el)">{{ el.title }}</div>
                  <img src="./assets/images/delete.png" alt="" @click="deleteTopicDom(el, index)">
                  <!-- <img class="tip-ico" src="./assets/images/delete.png" alt=""> -->
                </div>
                <div class="topic-content" @click="handlePopup(el)">{{ el.content }}</div>
                <div v-show="maskSub && el.cannotBeSelected" :class="el.select ? 'select-active' : 'select-sub'"
                  @click="handleSubSelect($event, index, el)"></div>
                <div class="topic-mask" v-show="maskSub && el.cannotBeSelected"></div>
                <!-- 弹出框 -->
                <div class="topic-pupop" v-if="el.topicPopup">
                  <div class="topic-pupop-title">{{ el.title }}</div>
                  <div class="topic-pupop-content">
                    <input class="topic-pupop-l" type="text" v-model="el.popupTopic" @input="limitInput(el, $event)" />
                    <div class="topic-pupop-r" @click="handleClosePopup(el)"></div>
                  </div>
                  <div class="topic-pupop-text">（以上编辑不含规则转换）</div>
                </div>
              </div>
            </template>
            <!-- 订阅确认按钮 -->
          </div>
          <div class="sure-btn-none" v-if="!maskSub"></div>
          <div class="sure-btn" v-else @click="handleSure">确认</div>

          <!-- 下部分 订阅发布 -->
          <div class="publish-subscribe-bottom">
            <template v-for="(item, index) in dataList.clientTwo" :key="index">
              <div v-if="item.isEmpyt" class="pubSub-none"></div>
              <div v-else class="pubSub-item" @click.self="getDomNode($event)">
                <div class="mask" v-show="maskDelet || maskEdit"></div>
                <div class="publish-title">
                  <text class="text">{{ item.title }}</text>
                  <img class="pubSub-img" src="./assets/images/right_arrow.png" alt=""
                    @click="handlePublish($event, index, 'clientTwo', item)">
                </div>
                <input class="node" :class="{ 'node-focused': item.focus }" type="text" placeholder="Node"
                  v-model="item.node" @dblclick="handleDataEdit(item, index, 'clientTwo')"
                  @focus="handleFocus('subscribe', index)" @blur="handleBlur('subscribe', index)">
                <div class="publish-bottom">
                  <text class="text">{{ item.subscribe }}</text>
                  <img class="pubSub-img" src="./assets/images/letf_arrow.png" alt=""
                    @click="handleSubscribe($event, index, 'clientTwo', item.unique)">
                </div>
                <div class="delete_btn" v-show="maskDelet">
                  <img src="./assets/images/delete_ioc.png" alt="" @click="dataDelete(index, 'clientTwo')">
                </div>
                <div class="edit_btn" v-show="maskEdit">
                  <img src="./assets/images/edit_ioc.png" alt="" @click="handleDataEdit(item, index, 'clientTwo')">
                </div>
                <!-- 弹出框 -->
                <!-- <div class="popup" v-if="item.isPopup">
                  <div class="popup-top">
                    <div class="popup-title">{{item.topic}}</div>
                    <img src="./assets/images/fork.png" alt="">
                  </div>
                  <div class="popup-context">
                    <input v-model="item.value" class="input-text" type="text" @focus="console.log(111)">
                    <img src="./assets/images/sure.png" alt="">
                  </div>
                </div> -->
              </div>
            </template>
          </div>
        </div>


      </div>
      <div class="content-r">
        <div class="popup-node-none" v-if="!popupSure"></div>
        <div class="popup-node" v-else>
          <img src="./assets/images/clos.png" class="close" @click="closePopup"></img>
          <!-- 话题转换列表 -->
          <div class="topic-change-list">
            <div class="title-list">话题转换列表</div>
            <div class="topic-list-box">
              <div class="topic-item" v-for="(item, index) in dataList.formsData.topicChangeList">
                <div class="node-name">{{ item.node }}</div>
                <div class="node-conten-init">{{ item.oldContent }}</div>
                <div class="node-description">{{ item.rule }}</div>
                <div class="node-modification">{{ item.newContent }}</div>
              </div>
            </div>
          </div>
          <!-- 节点属性编辑 -->
          <div class="node-attribute-editing">
            <div class="title-list">节点属性编辑</div>
            <div class="node-attribute-name">
              <div class="node-name">节点名称</div>
              <div class="node-box-input">
                <div class="node">{{ dataList.formsData.node }}</div>
                <!-- <input class="node-input" type="text" placeholder="点击可编辑" v-model="dataList.formsData.node"> -->
                <input class="node-input" type="text" v-model="nodeText" placeholder="可编辑">
              </div>
            </div>
            <div class="select-box">
              <div class="sub-box-left">
                <div class="sub-select-box">
                  <div class="select-title" @click="subTopics = !subTopics">已订阅话题</div>
                  <img class="drop-down" src="./assets//images/drop-down.png" alt="" @click="subTopics = !subTopics">
                  <div class="option-item-box" v-if="subTopics">
                    <div class="option-item" v-for="(el, index) in dataList.formsData.sublishedList"
                      @click="handleChangeContent(el, index, undefined, 'clientTwo')">{{ el.title }}
                    </div>
                  </div>
                </div>
                <div class="sub-title">{{ dataList.formsData.subTopic }}</div>
                <div class="sub-content">{{ dataList.formsData.subContent }}</div>
              </div>
              <div class="pub-box-right">
                <div class="sub-select-box">
                  <div class="select-title" @click="pubTopics = !pubTopics">已发布话题</div>
                  <img class="drop-down" src="./assets//images/drop-down.png" alt="" @click="pubTopics = !pubTopics">
                  <div class="option-item-box" v-if="pubTopics">
                    <div class="option-item" v-for="(el, index) in dataList.formsData.publishedList"
                      @click="handleChangeContent(el, index, nodeClient, 'clientOne')">{{ el.title }}
                    </div>
                  </div>
                </div>
                <div class="sub-title">{{ dataList.formsData.pubTopic }}</div>
                <div class="sub-content">{{ dataList.formsData.pubContent }}</div>
              </div>
            </div>
          </div>
          <!-- 话题内容转换 -->
          <div class="topic-content-conversion">
            <div class="conversion-title">话题内容转换（任选2项）</div>
            <div class="rules-box">
              <div class="rules-line" v-for="(el, index) in dataList.contentConversion">
                <div class="rules-item" v-for="(item, Index) in el.rules">
                  <div :class="item.select ? 'select' : 'unselect'" @click="handleSelect(index, Index)"></div>
                  <div class="rule-text">{{ item.rules }}</div>
                </div>
              </div>
            </div>
          </div>
          <!-- 确认按钮 -->
          <div class="sure-btn-popup" @click="handleSureBtn">
            确认
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
}

@import './app.less';
@import './appMedia.less';
</style>

<script setup>
import { ref, onMounted, onUnmounted, reactive, nextTick, watch, computed } from 'vue';

const dataList = reactive({
  clientOne: [
    // {title: '发布', node: 'Node', subscribe: '订阅', value: 'aaa', topic: 'Topic', isPopup: true, focus: false, isEmpyt: false},

  ],
  clientTwo: [
    // {title: '发布', node: 'Node', subscribe: '订阅', value: 'hello', topic: 'Topic', isPopup: false, focus: false, isEmpyt: false},
  ],
  topicChangeList: [
    { name: 'Node1', initialValue: 'abc1', content: '首字符改为1,字符后增加%', modificationValue: '1bc1%' },
    { name: 'Node2', initialValue: '123a', content: '首字符改为0,字符后增加#', modificationValue: '#023' },
    { name: 'Node2', initialValue: '123a', content: '首字符改为0,字符后增加#', modificationValue: '#023' },
    { name: 'Node2', initialValue: '123a', content: '首字符改为0,字符后增加#', modificationValue: '#023' },
    { name: 'Node2', initialValue: '123a', content: '首字符改为0,字符后增加#', modificationValue: '#023' },
  ],
  // 话题内容转换
  contentConversion: [
    {
      rules: [
        { rules: '字符前加X1', select: false, count: 0, oldRules: '字符前加X1' },
        { rules: '字符前加X2', select: false, count: 0, oldRules: '字符前加X2' },
        // { rules: '已订阅话题字符前添加@', select: false, count: 0, oldRules: '字符前添加@' },
        // { rules: '删减首字符', select: false, count: 0 },
        // { rules: '首字符改为a', select: false, count: 0 }
      ]
    },
    // {
    //   rules: [
    //     // { rules: '已订阅话题字符第2位插入#', select: false, count: 0, oldRules: '字符第2位插入#' },
    //     //   { rules: '删除字符$', select: false, count: 0 },
    //     //   { rules: '字符*改为&', select: false, count: 0 }
    //   ]
    // },
    {
      rules: [
        { rules: '字符后加Y1', select: false, count: 0, oldRules: '字符后加Y1' },
        { rules: '字符后加Y2', select: false, count: 0, oldRules: '字符后加Y2' },
        // { rules: '已订阅话题字符后添加%', select: false, count: 0, oldRules: '字符后添加%' },
        // { rules: '已订阅话题删减尾字符', select: false, count: 0, oldRules: '删减尾字符' },
        // { rules: '尾字符改为n', select: false, count: 0 }
      ]
    }
  ],
  topic: [],
  arrayList: [], // 储存DOM元素
  subDomList: [], // 订阅topic储存列表
  pubLines: [], // 存储发布线条信息的列表
  subLines: [], //存储订阅线条信息的列表
  formsData: {}, //表单数据
})


let ctx
let dashOffset = 0
let animationFrameId

/**
 * 发布画线
 * @param {DOMRect} rect1 第一个DOM元素的边界矩形
 * @param {DOMRect} rect2 第二个DOM元素的边界矩形
 * @param {string} name 标识符
 */
const drawLinePub = (rect1, rect2, name) => {


  let x1 = rect1.x + (rect1.width / 2);
  let x2 = rect2.x + (rect2.width / 2);
  let y1
  let y2


  // 找到中心点
  if (name == 'clientOne') {
    y1 = rect1.y + (rect1.height) + 10;
    y2 = rect2.y - 5;

    // y1 = rect1.y + 5;
    // y2 = rect2.y - 5;
  } else {
    y1 = rect1.y - 5;
    y2 = rect2.y + rect2.height + 10;
    // y1 = rect1.y - 5;
    // y2 = rect2.y + 5;
  }


  // 计算控制点
  const ctrlX1 = x1;
  const ctrlY1 = y1 + (y2 - y1) / 2;
  const ctrlX2 = x2;
  const ctrlY2 = y2 - (y2 - y1) / 2;

  ctx.beginPath();
  ctx.setLineDash([5, 5]);
  ctx.moveTo(x1, y1);
  // 画直线
  // ctx.lineTo(x2, y2);

  // 画曲线 （使用第一个控制点 (ctrlX1, ctrlY1) 和第二个控制点 (ctrlX2, ctrlY2) 来定义曲线的形状。 曲线最终到达终点 (x2, y2)）
  ctx.bezierCurveTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, x2, y2);
  ctx.strokeStyle = '#54b0d7';
  ctx.lineWidth = 1;
  ctx.stroke();

};

/**
 * @param rect1 第一个dom元素
 * @param rect2 第二个dom元素
 * @return 订阅画线
 */
const drawLineSub = (rect1, rect2, name) => {

  // const rect1 = document.querySelector('.addNode').getBoundingClientRect();
  // const rect2 = document.querySelector('.editNode').getBoundingClientRect();

  let x1 = rect1.x + (rect1.width / 2);
  let x2 = rect2.x + (rect2.width / 2);
  let y1
  let y2


  // 找到中心点
  if (name == 'clientOne') {
    y1 = rect1.y - 5;
    y2 = rect2.y + (rect2.height) + 5;
  } else {
    y1 = rect1.y + (rect1.height) + 5;
    y2 = rect2.y - 5;
  }



  // 计算控制点
  const ctrlX1 = x1 + (x2 - x1) / 2;
  const ctrlY1 = y1;
  const ctrlX2 = x2 - (x2 - x1) / 2;
  const ctrlY2 = y2;

  ctx.beginPath();
  ctx.setLineDash([5, 5]);
  ctx.moveTo(x1, y1);
  // 画直线
  // ctx.lineTo(x2, y2);

  // 画曲线 （使用第一个控制点 (ctrlX1, ctrlY1) 和第二个控制点 (ctrlX2, ctrlY2) 来定义曲线的形状。 曲线最终到达终点 (x2, y2)）
  ctx.bezierCurveTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, x2, y2);
  ctx.strokeStyle = '#e2a124';
  ctx.lineWidth = 1;
  ctx.stroke();
};

/**
 * @return 每一帧重现画，动画
 */
const animateLine = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.setLineDash([5, 10]);
  ctx.lineDashOffset = -dashOffset;

  // if (dataList.arrayList.length === 2) {
  //   drawLine(dataList.arrayList[0], dataList.arrayList[1]);
  // }

  // 绘制所有线条
  dataList.pubLines.forEach(line => {
    drawLinePub(line.rect1, line.rect2, line.name);
  });

  dataList.subLines.forEach(line => {
    drawLineSub(line.rect1, line.rect2, line.name);
  });

  dashOffset += 1;
  animationFrameId = requestAnimationFrame(animateLine);
};

/**
 * @param event DOM事件
 * @return 点击获取元素DOM
 */
const getDomNode = (event) => {
  return;
  if (dataList.arrayList.length >= 2) {
    dataList.arrayList = []
  }
  if (dataList.arrayList.length < 2) {
    dataList.arrayList.push(event.target.getBoundingClientRect())
  }
  if (dataList.arrayList.length === 2) {
    // drawLine(dataList.arrayList[0],dataList.arrayList[1]);
    dataList.pubLines.push({ rect1: dataList.arrayList[0], rect2: dataList.arrayList[1] });
    cancelAnimationFrame(animationFrameId);
    animateLine();
  }
}

/**
 * @param index 当前对象下标
 */
const handleFocus = (name, index) => {
  if (name == 'publish') {
    dataList.clientOne[index].focus = true
  } else {
    dataList.clientTwo[index].focus = true
  }
}

/**
 * @param index 当前对象下标
 */
const handleBlur = (name, index) => {
  if (name == 'publish') {
    dataList.clientOne[index].focus = false
  } else {
    dataList.clientTwo[index].focus = false
  }
}

const maskDelet = ref(false)
const maskEdit = ref(false)


/**
 * @param
 * @returns 新增节点
 */
const number = ref(0)
const addNode = () => {
  const flag1 = dataList.clientOne.length === 0 || dataList.clientOne.every((el) => el.isEmpyt);
  const flag2 = dataList.clientTwo.length === 0 || dataList.clientTwo.every((el) => el.isEmpyt);

  if (flag1 && flag2) {
    maskDelet.value = false
    maskEdit.value = false
  }
  // if (dataList.clientOne.length == 0 && dataList.clientTwo.length == 0) {
  //   maskDelet.value = false
  //   maskEdit.value = false
  //   // console.log(maskDelet.value, maskEdit.value)
  // }

  if (maskDelet.value || maskEdit.value) return alert('当前在删除或者编辑中！')
  const targetClient = (number.value % 6 === 0 || number.value % 6 === 3) ? dataList.clientOne : dataList.clientTwo;
  const maxNodes = 3;
  const newNode = {
    title: '发布',
    node: `Node${number.value}`,
    subscribe: '订阅',
    value: 'aaa',
    subTopic: '无',
    subContent: '无',
    pubTopic: '无',
    pubContent: '无',
    topicIndex: undefined,
    isPopup: true,
    focus: false,
    isEmpyt: false,
    unique: Math.random(),
    topicChangeList: [],
    subscribeTopics: [],
    postingTopics: [],
    subSelection: [
      { indexTopic: 0, select: false },
      { indexTopic: 1, select: false },
      { indexTopic: 2, select: false },
      { indexTopic: 3, select: false },
      { indexTopic: 4, select: false },
      { indexTopic: 5, select: false },
    ]
  };

  // 检查 dataList.clientOne 中是否有 isEmpyt 为 true 的
  const emptyIndex = dataList.clientOne.findIndex(item => item.isEmpyt === true);
  if (emptyIndex !== -1) {
    dataList.clientOne[emptyIndex] = newNode;
    number.value += 1;
    return;
  }

  // 检查 dataList.clientTwo 中是否有 isEmpyt 为 true
  const emptyIndexTwo = dataList.clientTwo.findIndex(item => item.isEmpyt === true)
  if (emptyIndexTwo !== -1) {
    dataList.clientTwo[emptyIndexTwo] = newNode;
    number.value += 1;
    return;
  }
  // 计算总节点
  const totalLength = dataList.clientOne.length + dataList.clientTwo.length;
  if (totalLength < maxNodes) {
    targetClient.push(newNode);
    number.value += 1;
  } else {
    alert(`最多只能添加3个`);
  }

};


/**
 * @param
 * @returns 删除按钮
 */

const deleteNode = () => {
  const flag1 = dataList.clientOne.length === 0 || dataList.clientOne.every((el) => el.isEmpyt);
  const flag2 = dataList.clientTwo.length === 0 || dataList.clientTwo.every((el) => el.isEmpyt);

  if (flag1 && flag2) {
    maskDelet.value = false
    maskEdit.value = false
    return alert('当前还没有新增节点')
  }
  maskDelet.value = !maskDelet.value
}

/**
 * @param
 * @returns 编辑按钮
 */
const editNode = () => {
  const flag1 = dataList.clientOne.length === 0 || dataList.clientOne.every((el) => el.isEmpyt);
  const flag2 = dataList.clientTwo.length === 0 || dataList.clientTwo.every((el) => el.isEmpyt);

  if (flag1 && flag2) {
    maskDelet.value = false
    maskEdit.value = false
    return alert('当前还没有新增节点')
  }
  maskEdit.value = !maskEdit.value
}


/**
 * @param
 * @returns 删除节点
 */
const deleteLinesByIndex = (indexItem, indexKey) => {
  dataList.pubLines = dataList.pubLines.filter(el => el[indexKey] !== indexItem);
  dataList.subLines = dataList.subLines.filter(el => el[indexKey] !== indexItem);
};

const dataDelete = (indexItem, name) => {
  const targetClient = dataList[name];
  const uniqueValue = targetClient[indexItem].unique;

  if (name === 'clientOne') {
    deleteLinesByIndex(indexItem, 'indexPubOne');
    deleteLinesByIndex(indexItem, 'indexSubOne');
  } else {
    deleteLinesByIndex(indexItem, 'indexPubTwo');
    deleteLinesByIndex(indexItem, 'indexSubTwo');
  }

  targetClient[indexItem].isEmpyt = true;

  dataList.topic = dataList.topic.map(item => {
    return {
      ...item,
      pubAssociation: item.pubAssociation.filter(el => el !== uniqueValue),
      subAssociation: item.subAssociation.filter(el => el !== uniqueValue)
    };
  });

  dataList.topic.forEach(item => {
    if (item.pubAssociation.length === 0 && item.subAssociation.length === 0) {
      item.isEmpyt = true;
    }
  });

};



/**
 * 
 * @param event 
 * @param index 
 * @param el 
 * @returns topic选中框
 */
const maskSub = ref(false) // 控制订阅蒙层
const IndexDom = ref(undefined) // 当前选中的DOM元素 
const currentIndexName = ref({ event: undefined, index: undefined, name: undefined, unique: undefined })
const handleSubSelect = (event, index, el) => {
  if (dataList.topic[index].select) return alert('已经订阅过了~')
  dataList.topic[index].select = !el.select
  // 添加节点唯一标识
  dataList.topic[index].subAssociation.push(currentIndexName.value.unique)

  dataList[currentIndexName.value.name][currentIndexName.value.index].subSelection.forEach(element => {
    if (dataList.topic[index].indexTopic == element.indexTopic) {
      element.select = dataList.topic[index].select
      // dataList.topic[index].select = true
    }
  });

  dataList.subDomList = dataList.topic.reduce((acc, item, currentIndex) => {
    if (item.select === true) {
      acc.push({ topDomLine: item.topicDom, topicDom: item.topicDom.getBoundingClientRect(), indexTopic: item.indexTopic, topicRandom: item.topicRandom });
    }
    return acc;
  }, []);
}


const nodeText = ref('')  // 绑定node节点model
const nodeClient = ref(undefined);
const selectedCount = ref(0);
const selectedRules = ref([]);  // 选中的规则
const history = ref([]); // 字符串测绘列表
const editDom = ref({ el: undefined, index: undefined, name: undefined })
/**
 * 编辑
 * @param el 
 * @param index 
 * @param name 
 * @param flag 是否为发布触发
 */
const endlessLoop = ref(false)
const handleDataEdit = (el, index, name, flag) => {
  endlessLoop.value = false
  nodeText.value = ''
  nodeClient.value = name
  // 清除打勾选项
  selectedCount.value = 0
  dataList.contentConversion.forEach(line => {
    line.rules.forEach(rule => {
      rule.select = false
    });
  });
  editDom.value = { el: el, index: index, name: name }
  dataList.formsData = el;
  selectedRules.value = [];
  // 提取公共逻辑到函数中
  const buildList = (sourceList, targetList) => {
    targetList = sourceList.reduce((acc, item) => {
      const matchingTopics = dataList.topic.filter(topic => item.indexTopic == topic.indexTopic);
      acc.push(...matchingTopics);
      return acc;
    }, []);
    if (targetList.length === 0) {
      targetList.push({ title: '无', content: '无' });
    }
    return targetList;
  };


  // 已发布
  dataList.formsData.publishedList = buildList(dataList.formsData.postingTopics, dataList.formsData.publishedList);
  // 已订阅
  dataList.formsData.sublishedList = buildList(dataList.formsData.subscribeTopics, dataList.formsData.sublishedList);

  if (!flag) popupSure.value = true;

  maskEdit.value = false;
  history.value = []

}

/**
 * @param 
 * @returns 订阅按钮
 */
const handleSubscribe = async (event, index, name, unique) => {
  currentIndexName.value.index = index
  currentIndexName.value.event = event
  currentIndexName.value.name = name
  currentIndexName.value.unique = unique

  dataList.topic.forEach(item => {
    item.select = false
    item.cannotBeSelected = true
  })

  await dataList[name][index].subSelection.forEach(element => {
    dataList.topic.forEach(el => {
      if (el.noSubLine.name == name && el.noSubLine.index == index) {
        el.cannotBeSelected = false
      }
      if (element.indexTopic == el.indexTopic) {
        el.select = element.select
      }
    })
  });

  dataList.subDomList = []
  if (IndexDom.value) {
    IndexDom.value = undefined
  }
  maskSub.value = !maskSub.value
  IndexDom.value = { IndexDom: event.currentTarget.parentNode.parentNode.getBoundingClientRect(), index: index, name: name }
}


/**
 * @param
 * @returns 确认订阅画线
 */
const handleSure = () => {
  dataList[IndexDom.value.name][IndexDom.value.index].subscribeTopics = []
  dataList.subDomList.forEach((el, index) => {
    dataList.subLines.push({
      eventSub: currentIndexName.value.event.target.parentNode.parentNode,
      eventTopic: el.topDomLine,
      rect1: el.topicDom,
      rect2: IndexDom.value.IndexDom,
      indexSubOne: IndexDom.value.name == 'clientOne' ? IndexDom.value.index : false,
      indexSubTwo: IndexDom.value.name == 'clientTwo' ? IndexDom.value.index : false,
      name: IndexDom.value.name,
      topicRandom: el.topicRandom
    })
    dataList[IndexDom.value.name][IndexDom.value.index].subscribeTopics.push({ indexTopic: el.indexTopic })
  })

  cancelAnimationFrame(animationFrameId);
  animateLine();
  maskSub.value = false
  handleDataEdit(editDom.value.el, editDom.value.index, editDom.value.name, true)
}



/**
 * 删除topic 节点
 * @param index 
 * @param name 
 */
const deleteTopicDom = (item, index) => {
  // 相关的线清除
  dataList.pubLines = dataList.pubLines.filter(el => el.topicRandom !== item.topicRandom);
  dataList.subLines = dataList.subLines.filter(el => el.topicRandom !== item.topicRandom);
  item.isEmpyt = true
  // 清除已发布话题postingTopics删除话题
  dataList[item.noSubLine.name][item.noSubLine.index].postingTopics =
    dataList[item.noSubLine.name][item.noSubLine.index].postingTopics.filter((el) => el.indexTopic != item.indexTopic)


  // 清除已订阅话题subscribeTopics删除话题
  item.subAssociation.forEach((el) => {
    // clientOne清除subscribeTopics
    dataList.clientOne[0].subscribeTopics = dataList.clientOne[0].subscribeTopics.filter((item) => item.indexTopic != item.indexTopic)
    dataList.clientOne[0].subSelection[item.indexTopic].select = false

    // clientTwo清除subscribeTopics
    dataList.clientTwo.forEach((twoEl) => {
      twoEl.subscribeTopics = twoEl.subscribeTopics.filter((list) => list.indexTopic != item.indexTopic)
      // 将当前删除的Topic select改为false
      twoEl.subSelection[item.indexTopic].select = false

    })
  })

  // 将节点里的选中修改为false
  // dataList.clientTwo.forEach()

  item.pubAssociation = []
  item.subAssociation = []
  handleDataEdit(editDom.value.el, editDom.value.index, editDom.value.name, true)
}


/**
 * @param
 * @returns 发布topic
 */
const indexTopic = ref(0)
const handlePublish = (event, index, name, item) => {
  // 删除过为空的
  const emptyIndex = dataList.topic.findIndex(item => item.isEmpyt === true);
  if (dataList.topic.length >= 6 && emptyIndex == -1) return alert('Topic最多六个');

  let randomNumber = Math.random()
  if (emptyIndex !== -1) {
    let addEmpyt = dataList.topic[emptyIndex].indexTopic
    dataList.topic[emptyIndex] = {
      title: `Topic${addEmpyt}`,
      // content: `A${addEmpyt}`,
      content: `A`,
      select: false,
      indexTopic: addEmpyt,
      noSubLine: { index: index, name: name },
      cannotBeSelected: true,
      topicPopup: false,  // 话题弹出框
      pubAssociation: [dataList[name][index].unique],
      subAssociation: [],
      isEmpyt: false,
      topicRandom: randomNumber,
      popupTopic: 'A',
      oldTopicValue: undefined
    };
    // number.value += 1;
  } else {
    dataList.topic.push(
      {
        title: `Topic${indexTopic.value}`,
        // content: `A${indexTopic.value}`,
        content: `A`,
        select: false,
        indexTopic: indexTopic.value,
        noSubLine: { index: index, name: name },
        cannotBeSelected: true,
        topicPopup: false,
        pubAssociation: [dataList[name][index].unique],
        subAssociation: [],
        isEmpyt: false,
        topicRandom: randomNumber,
        popupTopic: 'A',
        oldTopicValue: undefined
      }
    );
  }
  // 添加发布的postingTopics
  dataList[name][index].postingTopics.push({ indexTopic: emptyIndex !== -1 ? emptyIndex : indexTopic.value })
  // dataList[name][index].postingTopics.push({ indexTopic: indexTopic.value })
  indexTopic.value += 1
  nextTick(async () => {
    const lastTopic = await dataList.topic[emptyIndex !== -1 ? emptyIndex : dataList.topic.length - 1];
    if (lastTopic.topicDom) {
      dataList.pubLines.push({
        eventPub: event.currentTarget.parentNode.parentNode,
        eventTopic: lastTopic.topicDom,
        rect1: event.currentTarget.parentNode.parentNode.getBoundingClientRect(),
        rect2: lastTopic.topicDom.getBoundingClientRect(),
        indexPubOne: name == 'clientOne' ? index : false,
        indexPubTwo: name == 'clientTwo' ? index : false,
        name: name,
        topicRandom: randomNumber
      });
      cancelAnimationFrame(animationFrameId);
      animateLine();
    }
    handleDataEdit(item, index, name, true)
  });

};

/**
 * @param el 当前的对象
 * @param index 当前下标
 */

const currentTopic = ref(undefined)
const currentTopicSub = ref(undefined)
const handleChangeContent = (el, index, nodeClients, name) => {
  endlessLoop.value = false
  if (name == 'clientOne') { currentTopic.value = el }
  if (name == 'clientTwo') { currentTopicSub.value = el }

  subTopics.value = false
  pubTopics.value = false
  selectedCount.value = 0
  dataList[editDom.value.name][editDom.value.index].topicIndex = el.indexTopic

  // 清除打勾选项
  dataList.contentConversion.forEach(line => {
    line.rules.forEach(rule => {
      rule.select = false
    });
  });
  if (name == 'clientOne' || nodeClients == 'clientTwo') {
    dataList.formsData.pubTopic = el.title
    dataList.formsData.pubContent = el.content

  } else {
    dataList.formsData.subTopic = el.title
    dataList.formsData.subContent = el.content
    history.value.push(dataList.formsData.subContent)
  }

}

/**
 * 勾选规则
 */
const handleSelect = (lineIndex, ruleIndex) => {
  const rule = dataList.contentConversion[lineIndex].rules[ruleIndex];
  if (!rule.select && selectedCount.value >= 2) {
    alert('已选择两个规则，不能再选了');
    return;
  }

  rule.select = !rule.select;

  if (rule.select) {
    selectedCount.value++;
    rule.count++;
    applyRule(rule.rules);
  } else {
    selectedCount.value--;
    rule.count--;
    // 如果需要撤销规则效果，可以在这里实现
    undoRule(rule.rules);
  }
}

/**
 * 新增规则
 * @param rule
 */
const applyRule = async (rule) => {
  let newString = await dataList.formsData.subContent
  // if ((dataList.formsData.subContent == undefined && dataList.formsData.pubTopic == undefined)
  //   || (dataList.formsData.subContent == '无' && dataList.formsData.pubTopic == '无')
  // ) {
  //   dataList.contentConversion.forEach(line => {
  //     line.rules.forEach(rule => {
  //       rule.select = false
  //     });
  //   });
  //   selectedCount.value = 0
  //   return alert('请选择已订阅话题！！！')
  // }
  if ((dataList.formsData.subContent == undefined || dataList.formsData.subContent == '无')
  ) {
    dataList.contentConversion.forEach(line => {
      line.rules.forEach(rule => {
        rule.select = false
      });
    });
    selectedCount.value = 0
    return alert('请选择已订阅话题！！！')
  }

  if ((dataList.formsData.pubContent == '无' && dataList.formsData.pubTopic == '无')
    || (dataList.formsData.pubContent == undefined && dataList.formsData.pubTopic == undefined)) {
    dataList.contentConversion.forEach(line => {
      line.rules.forEach(rule => {
        rule.select = false
      });
    });
    selectedCount.value = 0
    return alert('暂无发布话题！！！')
  }
  history.value.push(dataList.formsData.subContent);

  switch (rule) {
    // case '已订阅话题字符前添加@':
    //   if (newString.length >= 6) {
    //     history.value.pop()
    //     // 取消选项勾选
    //     dataList.contentConversion.forEach(line => {
    //       line.rules.forEach(rule => {
    //         rule.select = false
    //       });
    //     });
    //     selectedCount.value = 0
    //     return alert('字符最多为六个')
    //   }
    //   dataList.formsData.subContent = '@' + newString;
    //   break;
    case '字符前加X1':
      if (newString.length >= 9) {
        history.value.pop()
        // 取消选项勾选
        dataList.contentConversion.forEach(line => {
          line.rules.forEach(rule => {
            rule.select = false
          });
        });
        selectedCount.value = 0
        return alert('字符最多为九个')
      }
      dataList.formsData.subContent = 'X1' + newString;
      break;
    case '字符前加X2':
      if (newString.length >= 9) {
        history.value.pop()
        // 取消选项勾选
        dataList.contentConversion.forEach(line => {
          line.rules.forEach(rule => {
            rule.select = false
          });
        });
        selectedCount.value = 0
        return alert('字符最多为九个')
      }
      dataList.formsData.subContent = 'X2' + newString;
      break;
    case '删减首字符':
      dataList.formsData.subContent = newString.slice(1);
      break;
    case '首字符改为a':
      dataList.formsData.subContent = 'a' + newString.slice(1);
      break;
    // case '已订阅话题字符第2位插入#':
    //   if (newString.length >= 6) {
    //     history.value.pop()
    //     // 取消选项勾选
    //     dataList.contentConversion.forEach(line => {
    //       line.rules.forEach(rule => {
    //         rule.select = false
    //       });
    //     });
    //     selectedCount.value = 0
    //     return alert('字符最多为六个')
    //   }
    //   dataList.formsData.subContent = newString.slice(0, 1) + '#' + newString.slice(1);
    //   break;

    case '删除字符$':
      dataList.formsData.subContent = newString.replace('$', '');
      break;
    case '字符*改为&':
      dataList.formsData.subContent = newString.replace('*', '&');
      break;
    case '字符后加Y1':
      if (newString.length >= 9) {
        history.value.pop()
        // 取消选项勾选
        dataList.contentConversion.forEach(line => {
          line.rules.forEach(rule => {
            rule.select = false
          });
        });
        selectedCount.value = 0
        return alert('字符最多为九个')
      }
      dataList.formsData.subContent = newString + 'Y1';
      break;
    case '字符后加Y2':
      if (newString.length >= 9) {
        history.value.pop()
        // 取消选项勾选
        dataList.contentConversion.forEach(line => {
          line.rules.forEach(rule => {
            rule.select = false
          });
        });
        selectedCount.value = 0
        return alert('字符最多为九个')
      }
      dataList.formsData.subContent = newString + 'Y2';
      break;
    case '已订阅话题删减尾字符':
      dataList.formsData.subContent = newString.slice(0, -1);
      break;
    case '尾字符改为n':
      dataList.formsData.subContent = newString.slice(0, -1) + 'n';
      break;
    default:
      break;
  }
};

/**
 * 回退
 * @param rule 
 */
const undoRule = (rule) => {
  if (history.value.length > 1) {

    dataList.formsData.subContent = history.value[history.value.length - 1];
    history.value.pop();
  }
};

/**
 * 当前发布死循环
 * 
 */

const dataPubCurrent = (currentItem, nodeItem, initialItem, processedItems = new Set()) => {
  if (processedItems.has(currentItem)) {
    return;
  }
  processedItems.add(currentItem);

  // 获取clientOne发布的节点
  const dataOneItem = currentItem?.pubAssociation?.reduce((acc, mapitem) => {
    const filteredItems = dataList.clientOne.filter((itemOne) => mapitem == itemOne.unique);
    if (filteredItems.length > 0) {
      acc.push(...filteredItems);
    }
    return acc;
  }, []);
  // console.log('dataOneItem:', dataOneItem);

  // 获取clientTwo发布的节点
  const dataTwoItem = currentItem?.pubAssociation?.reduce((acc, mapitem) => {
    const filteredItems = dataList.clientTwo.filter((itemTwo) => mapitem == itemTwo.unique);
    if (filteredItems.length > 0) {
      acc.push(...filteredItems);
    }
    return acc;
  }, []);

  // 将dataTwoItem里面所发布的内容都修改
  dataTwoItem?.forEach((item) => {
    item.subscribeTopics?.forEach((list) => {
      dataList.topic.forEach((elTopic, index) => {
        if (index == (list.indexTopic)) {
          if (elTopic != initialItem) {
            dataPubCurrent(elTopic, nodeItem, initialItem, processedItems);
          } else {
            endlessLoop.value = true
          }
        }
      });
    });
  });

  // 将dataOneItem里面所发布的内容都修改
  dataOneItem?.forEach((item) => {
    item.subscribeTopics?.forEach((list) => {

      dataList.topic.forEach((elTopic, index) => {
        if (index == (list.indexTopic)) {
          if (elTopic != initialItem) {
            dataPubCurrent(elTopic, nodeItem, initialItem, processedItems);

          } else {
            endlessLoop.value = true
          }
        }

      });
    });
  });
}

/**
 * 数据流递归
 * @param currentItem 当前topicitem
 * @param nodeItem  是topic点击还是node节点点击
 */
// const dataFlowRecursion = (currentItem, nodeItem) => {
//   // 获取clientOne订阅的节点
//   const dataOneItem = currentItem.subAssociation.reduce((acc, mapitem) => {
//     const filteredItems = dataList.clientOne.filter((itemOne) => mapitem == itemOne.unique);
//     if (filteredItems.length > 0) {
//       acc.push(...filteredItems);
//     }
//     return acc;
//   }, []);
//   // console.log('dataOneItem:', dataOneItem);

//   // 获取clientTwo订阅的节点
//   const dataTwoItem = currentItem.subAssociation.reduce((acc, mapitem) => {
//     const filteredItems = dataList.clientTwo.filter((itemTwo) => mapitem == itemTwo.unique);
//     if (filteredItems.length > 0) {
//       acc.push(...filteredItems);
//     }
//     return acc;
//   }, []);

//   // 将dataTwoItem里面所发布的内容都修改
//   dataTwoItem.forEach((item) => {
//     item.publishedList.forEach((list) => {
//       dataList.topic.forEach((elTopic) => {
//         if (elTopic.topicRandom == list.topicRandom) {
//           elTopic.oldTopicValue = elTopic.popupTopic
//           elTopic.popupTopic = currentItem.popupTopic
//           console.log('elTopic.popupTopic:', elTopic.popupTopic)
//           if (elTopic != currentItem) {
//             if (elTopic.oldTopicValue) {
//               let newStr = elTopic.content.replace(elTopic.oldTopicValue, nodeItem ? currentItem.content : currentItem.popupTopic);
//               elTopic.content = newStr
//             } else {
//               elTopic.content = currentItem.popupTopic
//             }
//             dataFlowRecursion(elTopic, nodeItem);
//           } else {
//             // 弹窗提示
//             console.log('elTopic:', elTopic);
//           }
//         }
//       })
//     })
//   })

//   // 将dataOneItem里面所发布的内容都修改
//   dataOneItem.forEach((item) => {
//     item.publishedList.forEach((list) => {
//       dataList.topic.forEach((elTopic) => {
//         if (elTopic.topicRandom == list.topicRandom) {
//           elTopic.oldTopicValue = elTopic.popupTopic
//           elTopic.popupTopic = currentItem.popupTopic

//           if (elTopic != currentItem) {
//             if (elTopic.oldTopicValue) {
//               let newStr = elTopic.content.replace(elTopic.oldTopicValue, nodeItem ? currentItem.content : currentItem.popupTopic);
//               elTopic.content = newStr
//               elTopic.oldTopicValue = currentItem.popupTopic
//             } else {
//               elTopic.content = currentItem.popupTopic
//               elTopic.oldTopicValue = currentItem.popupTopic
//             }
//             dataFlowRecursion(elTopic, nodeItem);
//           } else {
//             // 弹窗提示
//             console.log('elTopic:', elTopic);
//           }
//         }
//       })
//     })
//   })
// }

/**
 * 数据流递归
 * @param currentItem 当前topicitem
 * @param nodeItem 是topic点击还是node节点点击
 * @param processedItems 已经处理过的topic集合
 */
const dataFlowRecursion = (currentItem, nodeItem, processedItems = new Set()) => {
  if (processedItems.has(currentItem)) {
    return;
  }
  processedItems.add(currentItem);

  // 获取clientOne订阅的节点
  const dataOneItem = currentItem.subAssociation.reduce((acc, mapitem) => {
    const filteredItems = dataList.clientOne.filter((itemOne) => mapitem == itemOne.unique);
    if (filteredItems.length > 0) {
      acc.push(...filteredItems);
    }
    return acc;
  }, []);
  // console.log('dataOneItem:', dataOneItem);

  // 获取clientTwo订阅的节点
  const dataTwoItem = currentItem.subAssociation.reduce((acc, mapitem) => {
    const filteredItems = dataList.clientTwo.filter((itemTwo) => mapitem == itemTwo.unique);
    if (filteredItems.length > 0) {
      acc.push(...filteredItems);
    }
    return acc;
  }, []);

  // 将dataTwoItem里面所发布的内容都修改
  dataTwoItem?.forEach((item) => {
    item.publishedList?.forEach((list) => {
      dataList.topic?.forEach((elTopic) => {
        if (elTopic.topicRandom == list.topicRandom) {
          // console.log('Checking elTopic111:', elTopic, 'against currentItem111:', currentItem);
          if (elTopic != currentItem) {
            elTopic.oldTopicValue = elTopic.popupTopic;
            elTopic.popupTopic = currentItem.popupTopic;
            if (elTopic.oldTopicValue) {
              let newStr = elTopic.content.replace(elTopic.oldTopicValue, nodeItem ? currentItem.content : currentItem.popupTopic);
              elTopic.content = newStr;
            } else {
              elTopic.content = currentItem.popupTopic;
            }
            dataFlowRecursion(elTopic, nodeItem, processedItems);
          } else {
            // 弹窗提示
            console.log('elTopic:', elTopic);
          }
        }
      });
    });
  });

  // 将dataOneItem里面所发布的内容都修改
  dataOneItem?.forEach((item) => {
    item.publishedList?.forEach((list) => {
      dataList.topic?.forEach((elTopic) => {
        if (elTopic.topicRandom == list.topicRandom) {
          // console.log('Checking elTopic222:', elTopic, 'against currentItem222:', currentItem);
          if (elTopic != currentItem) {
            elTopic.oldTopicValue = elTopic.popupTopic;
            elTopic.popupTopic = currentItem.popupTopic;
            if (elTopic.oldTopicValue) {
              let newStr = elTopic.content.replace(elTopic.oldTopicValue, nodeItem ? currentItem.content : currentItem.popupTopic);
              elTopic.content = newStr;
              elTopic.oldTopicValue = currentItem.popupTopic;
            } else {
              elTopic.content = currentItem.popupTopic;
              elTopic.oldTopicValue = currentItem.popupTopic;
            }
            dataFlowRecursion(elTopic, nodeItem, processedItems);
          } else {
            // 弹窗提示
            console.log('elTopic:', elTopic);
          }
        }
      });
    });
  });
};


/**
 * 已订阅话题
 *  */
// const dataFlowRecursion = (currentItem, nodeItem) => {
//   const stack = []; // 用于模拟递归调用的栈

//   // 初始化栈
//   const dataOneItem = currentItem.subAssociation.reduce((acc, mapitem) => {
//     const filteredItems = dataList.clientOne.filter((itemOne) => mapitem == itemOne.unique);
//     if (filteredItems.length > 0) {
//       acc.push(...filteredItems);
//     }
//     return acc;
//   }, []);

//   const dataTwoItem = currentItem.subAssociation.reduce((acc, mapitem) => {
//     const filteredItems = dataList.clientTwo.filter((itemTwo) => mapitem == itemTwo.unique);
//     if (filteredItems.length > 0) {
//       acc.push(...filteredItems);
//     }
//     return acc;
//   }, []);

//   // 将dataTwoItem里面所发布的内容都修改
//   dataTwoItem.forEach((item) => {
//     item.publishedList.forEach((list) => {
//       dataList.topic.forEach((elTopic) => {
//         if (elTopic.topicRandom == list.topicRandom) {
//           stack.push(elTopic);
//         }
//       });
//     });
//   });

//   // 修改dataOneItem里面所发布的内容
//   dataOneItem.forEach((item) => {
//     item.publishedList.forEach((list) => {
//       dataList.topic.forEach((elTopic) => {
//         if (elTopic.topicRandom == list.topicRandom) {
//           stack.push(elTopic);
//         }
//       });
//     });
//   });

//   // 使用循环处理栈中的元素
//   while (stack.length > 0) {
//     const elTopic = stack.pop();

//     elTopic.oldTopicValue = elTopic.popupTopic;
//     elTopic.popupTopic = currentItem.popupTopic;
//     console.log('elTopic.popupTopic:', elTopic);

//     if (elTopic != currentItem) {
//       if (elTopic.oldTopicValue) {
//         let newStr = elTopic.content.replace(elTopic.oldTopicValue, nodeItem ? currentItem.content : currentItem.popupTopic);
//         elTopic.content = newStr;
//       } else {
//         elTopic.content = currentItem.popupTopic;
//       }
//       // 将相关元素加入栈中
//       dataList.topic.forEach((topic) => {
//         if (topic.topicRandom == elTopic.topicRandom && topic != elTopic) {
//           stack.push(topic);
//         }
//       });
//     } else {
//       // 弹窗提示
//       alert('elTopic == currentItem');
//     }
//   }
// };




const subTopics = ref(false)
const pubTopics = ref(false)
/**
 * 确认表单
 */
const popupSure = ref(false)
const handleSureBtn = async () => {

  await dataPubCurrent(currentTopic.value, true, currentTopic.value)
  if (endlessLoop.value) return alert(`${currentTopic.value.title}死循环，规则不成立`)

  if ((dataList.formsData.subContent == undefined && dataList.formsData.subTopic == undefined)
    || (dataList.formsData.subContent == '无' && dataList.formsData.subTopic == '无')

  ) {
    dataList.contentConversion.forEach(line => {
      line.rules.forEach(rule => {
        rule.select = false
      });
    });
    selectedCount.value = 0
    return alert('请选择已订阅话题！！！')
  }

  if ((dataList.formsData.pubContent == '无' && dataList.formsData.pubTopic == '无')
    || (dataList.formsData.pubContent == undefined && dataList.formsData.pubTopic == undefined)) {
    dataList.contentConversion.forEach(line => {
      line.rules.forEach(rule => {
        rule.select = false
      });
    });
    selectedCount.value = 0
    return alert('暂无发布话题！！！')
  }



  const newData = dataList.formsData
  dataList.contentConversion.forEach(line => {
    line.rules.forEach(rule => {
      if (rule.select) {
        selectedRules.value.push(rule.oldRules);
      }
    });
  });

  if (selectedRules.value.length == 0) {
    return alert('你还未选择内容转换')
  }

  // 最多添加五条
  if (dataList.formsData.topicChangeList.length >= 5) {
    dataList.formsData.topicChangeList.shift()
  }
  // 拼接规则
  const rule =
    `${selectedRules.value[selectedRules.value.length - 2] ? selectedRules.value[selectedRules.value.length - 2] + "、" : ''} 
  ${selectedRules.value[selectedRules.value.length - 1]}`

  // 将当前节点所有的发布消息同步更新

  // 将topic发布的修改
  // dataList[editDom.value.name][editDom.value.index].publishedList.forEach((publish) => {
  //   dataList.topic.forEach((topicItem) => {
  //     if (publish.indexTopic == topicItem.indexTopic) {
  //       // topicItem.title = publish
  //       topicItem.content = dataList[editDom.value.name][editDom.value.index].subContent
  //     }
  //   })
  // })
  // 只将选中的发布话题修改
  dataList.topic[currentTopic.value.indexTopic].content = dataList[editDom.value.name][editDom.value.index].subContent
  dataList.topic[currentTopic.value.indexTopic].oldTopicValue = currentTopic.value.popupTopic

  dataList[editDom.value.name][editDom.value.index] = dataList.formsData
  // node绑定
  dataList[editDom.value.name][editDom.value.index].node = nodeText.value == '' ? dataList[editDom.value.name][editDom.value.index].node : nodeText.value
  selectedCount.value = 0
  // 将当前修改值添加到formsData
  dataList.formsData.topicChangeList.push({ node: newData.node, oldContent: history.value[history.value.length - 2], newContent: newData.subContent, rule: rule })
  // 清除打勾选项
  dataList.contentConversion.forEach(line => {
    line.rules.forEach(rule => {
      rule.select = false
    });
  });

  selectedRules.value = [];
  dataList.formsData.subContent = currentTopicSub.value.content



  // ——————————————————————————————确认后更新topic————————————————————————————————————

  // 获取clientOne订阅的节点
  dataFlowRecursion(currentTopic.value, true)

}


/**
 * 关闭弹窗
 * @param el 
 */
const handleClosePopup = async (el) => {

  await dataPubCurrent(el, false, el)

  if (!endlessLoop.value) {
    await dataFlowRecursion(el, false)
  } else {
    el.topicPopup = false
    return alert(`${el.title}死循环，规则不成立`)
  }


  // console.log('el:', el)
  let newStr = el.content.replace(el.oldTopicValue, el.popupTopic);
  el.content = newStr
  // console.log('el.content:', el.content)
  el.topicPopup = false
}


/**
 * @param 
 * @returns 复位按钮
 */
const resetNode = () => {
  const resetArrays = {
    clientOne: [],
    clientTwo: [],
    topic: [],
    arrayList: [],
    pubLines: [],
    subLines: []
  };
  maskDelet.value = false
  maskEdit.value = false
  maskSub.value = false
  IndexDom.value = undefined
  popupSure.value = false
  indexTopic.value = 0
  endlessLoop.value = false


  Object.assign(dataList, resetArrays);
};

/**
 * 关闭弹窗
 */
const closePopup = () => {
  popupSure.value = false
}

/**
 * 限制6个字符
 */
const limitInput = (el, event) => {
  el.popupTopic = el.popupTopic.slice(0, 6);
};


/**
 * 双击打开topic弹窗
 */
const handlePopup = (el) => {
  endlessLoop.value = false
  el.oldTopicValue = el.popupTopic
  dataList.topic.forEach(el => el.topicPopup = false)
  el.topicPopup = true
}


watch(() => dataList.topic, (newVal) => {
  nextTick(() => {
    newVal.forEach((item, index) => {
      if (!item.topicDom) {
        const el = document.querySelectorAll('.topic-items')[index];
        if (el) {
          dataList.topic[index].topicDom = el;
        }
      }
    });
  });
}, { deep: true });


onMounted(() => {
  const canvas = document.getElementById('canvas');
  canvas.width = window.innerWidth; // 更新Canvas宽度为窗口宽度
  canvas.height = window.innerHeight; // 更新Canvas高度为窗口高度
  ctx = canvas.getContext('2d');



  // 监听窗口大小变化事件，重新绘制连线
  window.addEventListener('resize', () => {
    canvas.width = window.innerWidth; // 更新Canvas宽度为窗口宽度
    canvas.height = window.innerHeight; // 更新Canvas高度为窗口高度


    // ————————————————————————————————————————————————————
    // 获取所有需要监听的DOM元素
    const pubSubDom = document.querySelectorAll('.pubSub-item');
    const topicDom = document.querySelectorAll('.topic-items');

    // 使用ResizeObserver监听DOM元素的大小变化
    const resizeObserverPub = new ResizeObserver(entries => {
      entries.forEach(entry => {
        // 获取DOM元素的新尺寸
        const { width, height } = entry.contentRect;

        // 更新线条位置
        dataList.pubLines.forEach(line => {
          if (line.eventPub === entry.target) {
            line.rect1.x = entry.target.offsetLeft
            line.rect1.y = entry.target.offsetTop;
            line.rect1.height = height + 10
            line.rect1.width = width
          }
        });

        // 更新线条位置
        dataList.subLines.forEach(line => {
          if (line.eventSub === entry.target) {
            line.rect2.x = entry.target.offsetLeft
            line.rect2.y = entry.target.offsetTop;
            line.rect2.height = height + 15;
            line.rect2.width = width
          }
        });
      });
    });


    // 使用ResizeObserver监听DOM元素的大小变化
    const resizeObserverTopic = new ResizeObserver(entries => {
      entries.forEach(entry => {
        // 获取DOM元素的新尺寸
        const { width, height } = entry.contentRect;

        // 更新发布线条topic位置
        dataList.pubLines.forEach(line => {
          if (line.eventTopic === entry.target) {
            line.rect2.x = entry.target.offsetLeft
            line.rect2.y = entry.target.offsetTop;
            line.rect2.height = height - 10;
            line.rect2.width = width
          }
        });

        // 更新订阅线条topic位置
        dataList.subLines.forEach(line => {
          if (line.eventTopic === entry.target) {
            line.rect1.x = entry.target.offsetLeft
            line.rect1.y = entry.target.offsetTop;
            line.rect1.height = height;
            line.rect1.width = width
          }
        });
      });
    });



    // 开始监听所有DOM元素
    pubSubDom.forEach(element => {
      resizeObserverPub.observe(element);
    });
    topicDom.forEach(element => {
      resizeObserverTopic.observe(element);
    });
  });
});

onUnmounted(() => {
  cancelAnimationFrame(animationFrameId);
});

</script>
